鐵人賽 React javascript nodejs
鐵人賽第19天,我們來好好了解一下useEffect,同時,我們也會學習React的生命週期!![]()
React定義了component的生命週期,提供開發者能夠精準的設置相對應的動作。
Render做一個時間軸的分隔線,後面的代表component已繪製於畫面中,其中:
- ComponentDidMount: 元件已經完成繪製
- *ComponentDidUpdate: state已經更新完成
- ComponrntWillUnMount: 元件即將移除畫面
EffectApp.js,同時將index.js引入使用。EffectApp組件組成有:
- 一個
div顯示title- 一個
button,有toggle的功能,實現state的切換,決定title是否顯示
//EffectApp.js
import React, { useState, useEffect } from "react"; //<-- import引入 useEffect
export default function EffectApp() {
const [state, setState] = useState(true);
// 建立一個useEffect
useEffect(() => {
console.log("ComponentDidMount...");
});
let handleClick = (setState) => {
return (e) => {
setState(!state);
};
};
return (
<>
<button onClick={handleClick(setState)}>{state?"delete":"show"}</button>
<div>{state&& "Learn useEffect"}</div>
</>
);
}
ComponentDidMount...已經顯示於console window中,代表所有的component已經顯示於畫面之上囉!//EffectApp.js
import React, { useState, useEffect } from "react";
export default function EffectApp() {
const [state, setState] = useState(true);
useEffect(() => {
console.log("ComponentDidMount...");
return () => console.log("ComponentDidUpdate!!!"); //<-- 在這裡回傳一個func,當狀態改變時,React會自動呼叫這個函式執行
});
let handleClick = (setState) => {
return (e) => {
setState(!state);
};
};
return (
<>
<button onClick={handleClick(setState)}>{state?"delete":"show"}</button>
<div>{state&& "Learn useEffect"}</div>
</>
);
}

console window會依序印出
- 狀態改變 => 呼叫回傳的func
return () => console.log("ComponentDidUpdate!!!");- 元件消失或出現 => 呼叫
console.log("ComponentDidMount...");
Array,提供給React決定要呼叫的//EffectApp.js
import React, { useState, useEffect } from "react";
export default function EffectApp() {
const [state1, setState1] = useState(true);
const [state2, setState2] = useState(true);
// for state1
useEffect(() => {
console.log("*** area1 ***");
console.log("[state1]: ComponentDidMount...");
return () => console.log("[state1]: ComponentDidUpdate!!!");
}, [state1]);
// for state2
useEffect(() => {
console.log("=== area2 ===");
console.log("[state2]: ComponentDidMount...");
return () => console.log("[state2]: ComponentDidUpdate!!!");
},[state2]);
let handleClick = (setState, aState) => {
return (e) => {
setState(!aState);
};
};
return (
<>
<button onClick={handleClick(setState1, state1)}>{state1?"delete1":"show1"}</button>
<div>{state1&& "area1"}</div>
<br/>
<button onClick={handleClick(setState2, state2)}>{state1?"delete2":"show2"}</button>
<div>{state2&& "area2"}</div>
</>
);
}
ComponentDidMount都有被呼叫,符合期待
ComponentDidUpdate先被觸發,因為state1確實被更新了!area1的title消失,因此呼叫ComponentDidMount,符合預期!
area1的按鈕一樣,也符合我們對state2的預期
useEffect的第二個變數,給予空的Array,來看看會有什麼有趣的事//EffectApp.js
...
// for state2
useEffect(() => {
console.log("=== area2 ===");
console.log("[state2]: ComponentDidMount...");
return () => console.log("[state2]: ComponentDidUpdate!!!");
},[]); //<-- 給空的陣列,看看會有什麼有趣的事
...

![]()
area2的ComponentDidMount在畫面一開始顯示時有被呼叫,之後,不管我怎麼按area2的按鈕,他都不會有任何反應,React會依據第二個參數的Array內容,來決定是否觸發ComponentDidMount及ComponentDidUpdate
useEffect第二個參數給予空的陣列,僅會執行一次!React Hook中,ComponentWillUnMount及ComponentDidUpdate都會跟著呼叫你回傳的函示。useEffect(()=>{
// component did Mount
return ()=>{
// component did update
// componrnt will unMount
}
}, [
// 空陣列代表僅執行一次,
// 放入state或component,代表只要他們有變動,就會觸發呼叫useEffect
//])
useEffect及React lifecycle之間的關係,useEffect有很多進階的應用,我們會在未來好好的跟各位詳談,請期待!